<template>
  <div 
    :class="[
      'bx-auto-complete',
      'bx-glass',
      {
        'bx-auto-complete--disabled': disabled,
        'bx-auto-complete--focused': focused
      }
    ]"
    @click.stop
  >
    <BxInput
      ref="inputRef"
      v-model="inputValue"
      :placeholder="placeholder"
      :disabled="disabled"
      :readonly="readonly"
      :size="size"
      @focus="handleFocus"
      @blur="handleBlur"
      @input="handleInput"
      @keydown="handleKeydown"
    />

    <div 
      v-if="showDropdown"
      class="bx-auto-complete__dropdown bx-glass"
    >
      <ul class="bx-auto-complete__list">
        <li 
          v-for="(item, index) in filteredOptions"
          :key="index"
          :class="[
            'bx-auto-complete__item',
            {
              'bx-auto-complete__item--active': activeIndex === index
            }
          ]"
          @click="handleSelect(item)"
          @mouseenter="activeIndex = index"
        >
          <slot name="item" :item="item">
            {{ item }}
          </slot>
        </li>
        <li v-if="!filteredOptions.length" class="bx-auto-complete__empty">
          <slot name="empty">
            <BxEmpty description="无匹配数据" size="small" />
          </slot>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import { ref, computed, watch, nextTick } from 'vue'
import BxInput from '../input/BxInput.vue'
import BxEmpty from '../data-display/BxEmpty.vue'

export default {
  name: 'BxAutoComplete',
  components: {
    BxInput,
    BxEmpty
  },
  props: {
    modelValue: {
      type: String,
      default: ''
    },
    options: {
      type: Array,
      default: () => []
    },
    placeholder: {
      type: String,
      default: ''
    },
    disabled: {
      type: Boolean,
      default: false
    },
    readonly: {
      type: Boolean,
      default: false
    },
    size: {
      type: String,
      default: 'medium',
      validator: (value) => ['small', 'medium', 'large'].includes(value)
    },
    filterMethod: {
      type: Function,
      default: (query, option) => {
        return String(option).toLowerCase().includes(query.toLowerCase())
      }
    },
    debounce: {
      type: Number,
      default: 0
    }
  },
  emits: ['update:modelValue', 'change', 'select', 'focus', 'blur'],
  setup(props, { emit }) {
    const inputRef = ref(null)
    const inputValue = ref(props.modelValue)
    const focused = ref(false)
    const showDropdown = ref(false)
    const activeIndex = ref(-1)
    let debounceTimer = null

    const filteredOptions = computed(() => {
      if (!inputValue.value) return props.options
      return props.options.filter(option => props.filterMethod(inputValue.value, option))
    })

    const handleFocus = (event) => {
      focused.value = true
      showDropdown.value = true
      emit('focus', event)
    }

    const handleBlur = (event) => {
      focused.value = false
      // 延迟关闭，以便点击选项
      setTimeout(() => {
        showDropdown.value = false
        activeIndex.value = -1
      }, 150)
      emit('blur', event)
    }

    const handleInput = (event) => {
      const value = event.target.value
      inputValue.value = value
      emit('update:modelValue', value)
      emit('change', value)

      if (debounceTimer) {
        clearTimeout(debounceTimer)
      }
      debounceTimer = setTimeout(() => {
        showDropdown.value = true
        activeIndex.value = -1
      }, props.debounce)
    }

    const handleSelect = (item) => {
      inputValue.value = item
      emit('update:modelValue', item)
      emit('change', item)
      emit('select', item)
      showDropdown.value = false
      inputRef.value?.blur()
    }

    const handleKeydown = (event) => {
      if (!showDropdown.value || !filteredOptions.value.length) return

      switch (event.key) {
        case 'ArrowDown':
          event.preventDefault()
          activeIndex.value = (activeIndex.value + 1) % filteredOptions.value.length
          break
        case 'ArrowUp':
          event.preventDefault()
          activeIndex.value = (activeIndex.value - 1 + filteredOptions.value.length) % filteredOptions.value.length
          break
        case 'Enter':
          event.preventDefault()
          if (activeIndex.value !== -1) {
            handleSelect(filteredOptions.value[activeIndex.value])
          } else {
            // 如果没有选中项，则直接触发input的blur事件，让其处理
            inputRef.value?.blur()
          }
          break
        case 'Escape':
          event.preventDefault()
          showDropdown.value = false
          inputRef.value?.blur()
          break
      }
    }

    watch(() => props.modelValue, (newVal) => {
      if (newVal !== inputValue.value) {
        inputValue.value = newVal
      }
    })

    return {
      inputRef,
      inputValue,
      focused,
      showDropdown,
      activeIndex,
      filteredOptions,
      handleFocus,
      handleBlur,
      handleInput,
      handleSelect,
      handleKeydown
    }
  }
}
</script>

<style scoped>
.bx-auto-complete {
  position: relative;
  display: inline-block;
  width: 240px;
  font-family: var(--bx-font-family);
}

.bx-auto-complete__dropdown {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  width: 100%;
  max-height: 200px;
  overflow-y: auto;
  border: 1px solid var(--bx-glass-border);
  border-radius: var(--bx-radius-medium);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  z-index: 1000;
  animation: bx-fade-in-up 0.2s ease-out;
}

.bx-auto-complete__list {
  list-style: none;
  padding: 4px 0;
  margin: 0;
}

.bx-auto-complete__item {
  padding: 8px 12px;
  cursor: pointer;
  color: var(--bx-text-primary);
  transition: background-color var(--bx-transition-fast);
}

.bx-auto-complete__item:hover,
.bx-auto-complete__item--active {
  background: var(--bx-glass-bg-hover);
}

.bx-auto-complete__empty {
  padding: 16px;
  text-align: center;
  color: var(--bx-text-tertiary);
}

@keyframes bx-fade-in-up {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .bx-auto-complete {
    width: 100%;
  }
}
</style>

